$KCODE = 'u'
require 'jcode'
require 'rubygems'
require 'singleton'
require 'hpricot'
require 'open-uri'
require 'iconv'
require 'htmlentities'
require 'dm-core'
require 'progressbar'
require 'csv'


DataMapper::setup(:default, "sqlite3:///#{Dir.pwd}/cumulards.db")

module IlsCumulentLesMandats
  BASE_URL_ASSEMBLEE = "http://www.assemblee-nationale.fr/13/tribun/"
  BASE_URL_SENAT     = "http://www.senat.fr"
  ICONV = Iconv.new('utf-8', 'iso8859-1')
  HTMLKODER = HTMLEntities.new
  
  class Singleton
    attr_writer :verbose
    def initialize(options = {})
      @verbose ||= false
      if Elu.auto_upgrade! && @verbose
        puts "# Création de la table Elus"
      end
      if Mandat.auto_upgrade! && @verbose
        puts "# Création de la table Mandats"
      end
    end
    def fetch
      Elu.all.destroy!
      Mandat.all.destroy!
      fetch_deputes
      fetch_senateurs
    end
    def fetch_deputes
      url = BASE_URL_ASSEMBLEE + "comm3.asp"
      doc = Hpricot(ICONV.iconv(URI.parse(url).read))
      liens = doc.search("a").select do |link|
        link.attributes['href'] =~ /fiches_id\//
      end
      #liens = liens[0..5]
      puts "# Fetching députés..."
      pbar = ProgressBar.new("Fetching", liens.size)
      deputes = liens.collect do |lien|
        # depute = Depute.new( HTMLKODER.decode(lien.inner_html),
        #                     BASE_URL_ASSEMBLEE + lien.attributes['href'], @verbose )
        depute = Depute.new
        depute.nom_brut = HTMLKODER.decode(lien.inner_html)
        depute.url = BASE_URL_ASSEMBLEE + lien.attributes['href']
        depute.verbose = @verbose
        depute.save
        depute.fetch
        pbar.inc
      end
      pbar.finish
    end
    def find_deputes
      deputes = Depute.all
      deputes.each do |depute|
        puts depute
      end
    end
    def fetch_senateurs
      url = BASE_URL_SENAT + "/listes/senatl.html"
      doc = Hpricot(ICONV.iconv(URI.parse(url).read))
      liens = doc.search("a").select do |link|
        link.attributes['href'] =~ /^\/senfic\//
      end
      #liens = liens[0..5]
      puts "# Fetching sénateurs..."
      pbar = ProgressBar.new("Fetching", liens.size)
      liens =  liens.collect do |lien|
        senateur = Senateur.new
        senateur.nom_brut = HTMLKODER.decode(lien.inner_html)
        senateur.url = BASE_URL_SENAT + lien.attributes['href']
        senateur.verbose = @verbose
        senateur.save
        senateur.fetch
        pbar.inc
      end
      pbar.finish
    end
    def find_senateurs
      senateurs = Senateur.all
      senateurs.each do |senateur|
        puts senateur
      end
    end
    def csv_senateurs
      senateurs = Senateur.all
      puts "Writing senateurs.csv"
      puts "=" *72
      pbar = ProgressBar.new("Writing", senateurs.size)
      CSV.open('senateurs.csv', 'w', ';') do |wr|
        wr << ['nom','prenom','cumulard', 'mandat1', 'mandat2', 'mandat3', 'mandat4', 'mandat5']
        senateurs.each do |s|
          l = [s.nom, s.prenom, s.cumulard? ? "OUI" : "NON"]
          (0..4).each do |n|
            c = ""
            c = s.mandats.at(n).nom if s.mandats.at(n)
            l << c
          end
          wr << l
          pbar.inc
        end
      end
      pbar.finish
    end
  end
end

class Elu
  include DataMapper::Resource
  property :id, Serial
  property :type, Discriminator
  property :nom_brut, String
  property :url, String
  property :created_at, DateTime
  property :updated_at, DateTime
  has n, :mandats

  attr_writer :verbose
  def initialize(*params)
    super(params)
    self.created_at ||= Time.now
    self.updated_at ||= Time.now
    @verbose ||= false
  end
  def cumulard?
    mandats.size > 0
  end
  def type_d_elu
    if is_a? Depute
      "Député"
    else
      "Sénateur"
    end
  end
  
  def nom
    @nom_brut.strip
  end
  
  def prenom
  end
  
  def titre
  end
  
  def to_s
    str = "-" * 72 + "\n"
    str << "Nom:        " + nom + "\n" unless titre.blank?
    str << "Nom:        " + nom + "\n"
    str << "Prénom:     " + prenom + "\n" unless prenom.blank?
    str << "Type:       " + type_d_elu  + "\n"
    str << "Cumulard ?: " + (cumulard? ? "OUI" : " - ")  + "\n"
    str << "-" * 72
    str << "\n"
  end
  
  private 
  
  def page
    @page ||= Hpricot(IlsCumulentLesMandats::ICONV.iconv(URI.parse(self.url).read))
  end
end

class Depute < Elu
  def fetch
    puts "Fetching Député: #{@nom_brut} (#{@url})..." if @verbose
    page.search("#P9 + h1 + ul li ").collect! do |lien|
      mandats.build(:nom_brut => lien.inner_html)
    end
    save
  end
end

class Senateur < Elu
  def fetch
    #puts to_s
    puts "Fetching Sénateur: #{@nom_brut} (#{@url})..." if @verbose
    page.search("#contenu > table > tr").collect! do |frag|
      #puts frag.to_html
      frag.search('td').each do |td|
        #puts td
        if td.inner_html.strip == "Mandats locaux"
          ## on tape dans le 2ème td suivant...
          t = td.siblings_at(2).first.inner_text.strip
          t.gsub! /\?/, ''
          m = t.split("\n").collect do |str|
            str.gsub(/ +/,' ') unless str.blank?
          end
          #puts m.compact.inspect
          m.compact.each do |nom|
            mandats.build(:nom_brut => nom)
            #puts mandats
          end
        end
      end
    end
    save
  end
  
  def nom
    #@nom_brut.gsub /[A-Z]/mu
    elts = @nom_brut.split
    prenom = elts.slice!(-1,1)
    nom = ""
    if elts.size > 1
      nom = elts.join(" ")
    else
      nom = elts.first
    end
    nom
  end
  
  def prenom
    @nom_brut.split.last
  end
  
  private
  
  def capitalize(str)
    first = str.slice!(0,1).upcase
    first << str.downcase.tr("ÀÁÂÃÄÅÇÈÉÊËÌÍÎÏÑÒÓÔÕÖØÙÚÛÜÝ", "àáâãäåçèéêëìíîïñòóôõöøùúûüý")
  end
  
  
end

class Mandat
  include DataMapper::Resource
  property :id, Serial
  property :nom_brut, String
  property :elu_id, Integer, :key => true
  property :created_at, DateTime
  property :updated_at, DateTime

  belongs_to :elu
  
  def initialize(params)
    super
    self.created_at ||= Time.now
    self.updated_at ||= Time.now
  end
  
  def nom
    nom_brut
  end
end